//app.js
// 环境变量 开发环境引入: dev 正式环境引入: prod
import {
  environment
} from '/environment/dev'

import Dialog from './miniprogram_npm/@vant/weapp/dialog/dialog';
App({
  globalData: {
    userInfo: null, // 用户数据
    environment: null, // 环境配置数据
    jsCode: '' // jsCode值
  },
  // 设置全局组件样式
  options: {
    styleIsolation: 'shared',
  },
  onLaunch: function () {
    debugger
    this.nfc = wx.getNFCAdapter(); // 务必先初始化
    this.globalData.environment = environment
    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
        this.globalData.jsCode = res.code
      }
    })
    // 获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting['scope.userInfo']) {
          // 已经授权，可以直接调用 getUserInfo 获取头像昵称，不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求，可能会在 Page.onLoad 之后才返回
              // 所以此处加入 callback 以防止这种情况
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  globalData: {
    userInfo: null
  },







  // 启动NFC 服务；启动之前先检查NFC状态
  startNFCServer: async function () {
    const nfc = this.nfc;
    const nfca = nfc.getNfcA()
    const nfca2 = nfc.getNfcA();
    const nfca3 = nfc.getNfcA();

    nfca2 === nfca & console.log('nfca2===nfca:')
    nfca3 === nfca & console.log('nfca3===nfca:')
    nfca2 === nfca3 & console.log('nfca2===nfca3:')

    const connectStatus = await this.isConnectPromise(nfca);
    console.log("connectStatus:", connectStatus)
    await this.stopDiscovery()

    if (this.settingOk != true) {
      this.settingOnDiscoverd(this.nfc)
      this.settingOk = true; //只需要设置一次即可
    }
    const startRes = await this.NFCStartDiscovery(nfc);
    if (startRes == null) {} else {
      wx.showToast({
        title: '手机已检测到测温贴',
      })
    }
    console.log("startRes:", startRes)
  },


  startTemperature: async function (nfc) {
    // const nfc = this.nfc;
    if (nfc === this.nfc) {
      console.log('是同一个NFC实例')
    }

    if (nfc == null) {
      return null;
    }
    const nfca = nfc.getNfcA()
    if (nfca == this.nfc.getNfcA()) {
      console.log('是同一个NFCA实例')
    }
    if (nfca == null) {
      return null
    }
    const connectRes = await this.connectPromise(nfca)
    console.log('connectRes:', connectRes)

    return (Math.random()*(37-35+1)+35).toFixed(2);

    // const tmpCMDRes = await this.NFCTempWork(nfca, this.string2buffer('40c00600000000'));
    // console.log('tmpCMDRes:', tmpCMDRes)
    // const cmd = this.ab2hex(tmpCMDRes.data);
    // console.log('开启温度命令返回值:', cmd)
    // if (cmd == '00faff') {
    //   const delayAwhile = await this.delay(400) // 延时400ms再执行下一个命令
    //   const connectRes2 = await this.connectPromise(nfca)
    //   console.log('connectRes:', connectRes2)
    //   const tmpRes = await this.NFCTempWork(nfca, this.string2buffer('40c08400000000'))
    //   if (tmpRes.data == null) {
    //     wx.showToast({
    //       title: '接触时请勿移动',
    //       icon: 'none'
    //     })
    //     return null
    //   } else {
    //     console.log('获取温度返回值tmpRes:', tmpRes)
    //     const hexTmp = this.ab2hex(tmpRes.data)
    //     console.log('温度16进制字符串:', hexTmp)
    //     const tp = this.getTp(hexTmp);
    //     console.log('温度:', tp)
    //     return tp
    //   }

    // } else {
    //   return null
    // }
  },


  settingOnDiscoverd(nfc) {
    nfc.onDiscovered(this.onDiscoveredFun);
  },
  onDiscoveredFun: async function (disCoverRes) {
    console.log('disCoverRes:', disCoverRes)
    // this.stopDiscovery();
    const NFCId = this.ab2hex(disCoverRes.id);
    if (this.onDiscoveredCallBack) {
      this.onDiscoveredCallBack(NFCId.toUpperCase())
    }
  },
  stopDiscovery: async function () {
    const nfc = this.nfc;
    nfc.getNfcA().close();
    const stopRes = await this.stopDiscoveryPromise(nfc)
    console.log('stopRes:', stopRes)
  },

  connectPromise: async function (nfca) {
    return new Promise((resolve, reject) => {
      nfca.connect({
        success: res => resolve && resolve(res),
        fail: f => {
          console.log(f);
          resolve && resolve(f)
        }
      })
    })
  },
  delay(milSec) {
    return new Promise(resolve => {
      setTimeout(resolve, milSec)
    })

  },
  isConnectPromise: function (nfca) {
    return new Promise((resolve, reject) => {
      nfca.isConnected({
        success: res => resolve && resolve(res),
        fail: f => {
          console.log(f);
          resolve && resolve(f)
        }
      })
    })
  },
  ab2hex(buffer) {
    var hexArr = Array.prototype.map.call(
      new Int16Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  },

  stopDiscoveryPromise: async function (nfc) {
    return new Promise((resolve, reject) => {
      nfc.stopDiscovery({
        success: res => resolve && resolve(res),
        fail: f => resolve && resolve(f)
      });
    })
  },
  NFCTempWork: function (nfca, code) {
    return new Promise((resolve, reject) => {
      nfca.transceive({
        data: code,
        success: res => resolve && resolve(res),
        fail: f => {
          console.log(f);
          resolve && resolve(f)
        }
      })
    })
  },


  // 开始监听发现NFC模块

  NFCStartDiscovery: function (nfc) {
    return new Promise((resolve, reject) => {
      nfc.startDiscovery({
        success: res => resolve && resolve(res),
        fail: err => {
          resolve && resolve(null)
          console.log(err)
          if (err.errCode === 13021) return
          Dialog.confirm({
            title: '初始化NFC模块失败，请检查NFC是否已开启',
            showCancelButton: false,
            confirmButtonText: '知道了'
          })
        }
      })
    })
  },






  /// 工具类
  ab2hex(buffer) {
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  },


  string2buffer(str) {
    let val = ""
    if (!str) return;
    let length = str.length;
    let index = 0;
    let array = []
    while (index < length) {
      array.push(str.substring(index, index + 2));
      index = index + 2;
    }
    val = array.join(",");
    // 将16进制转化为ArrayBuffer
    var hex_array = array.map(el => parseInt(el, 16))
    let buffer = new ArrayBuffer(array.length)
    let dataView = new DataView(buffer)
    hex_array.forEach((element, index) => {
      dataView.setUint8(index, element)
    });
    return buffer
  },
  getTp(hex) {

    // input: 7300================定义温度为 fvaluelet fvalue = 0调用大小端方法反转 input。得到 0073。这里有大小端的概念 需要将两个数据反过来let result = 0073将 result 转换为2进制数据let revert2Bytes = 000000001110011获取 symbol。 symbol 为从第 6 位开始取，取一位。当前为 0let symbol = 0将 result从第 7 位开始取。取到最后 获取最新的 resultresult = 001110011将 result 转为 10 进制result = 115判断 symbol 是否等于 0如果等于0， 温度为 result/4.0 = 28.75℃假如不等于0intValue = 0x1ff-(result-1);fValue = result / 4.0;fValue = -1*fValue;//转换为负数NSLog(@"温度为%.2f", fValue);
    let res = hex.slice(-4);
    console.log('去掉前面2位为:', res)
    res = (res.slice(-2) + res).slice(0, 4)
    console.log("调用大小端方法反转后16进制:", res)
    let revert2Bytes = ('0000000000000000' + parseInt(res, 16).toString(2)).slice(-16)
    console.log("反转后的二进制字符串:", revert2Bytes)
    let symbol = parseInt(revert2Bytes[6])
    console.log('symbol第6位开始取；取一位为:', symbol) //
    res = revert2Bytes.slice(7);
    console.log('从第7位开始后的二进制:', res);
    res = parseInt(res, 2)
    console.log('转化10进制后为:', res) //
    if (symbol == 0) {
      return res / 4
    } else {
      return (0x1ff - res + 1) / 4
    }
  },




  // 连续多次测温方法

  mutipleTemp: async function (nfca) {
    // 1:首先发送指令获取数据大小
    const connectRes = await this.connectPromise(nfca)
    console.log('connectRes:', connectRes)
    const dataSizeRes = await this.NFCTempWork(nfca, this.string2buffer('40b1b054000300'));
    const dataSizeParse = this.ab2hex(dataSizeRes.data) // 得到16进制字符串；
    console.log('获取数据大小:', dataSizeParse)
    // 2:从第四位开始，取两位长度。得到数据 13将16 进制的 13 转换为 10 进制 为 19再将得到的值乘以 1024
    const subStr = dataSizeParse.substring(4);
    const decNum = parseInt(subStr, 16);
    const allDataSize = decNum * 1024;
    console.log('数据大小:', allDataSize)
    // 3:发送指令获取测温总次数;
    const tempTotolTimeRes = await this.NFCTempWork(nfca, this.string2buffer('40b1b094000200'));
    const tempTotolTimeParse = this.ab2hex(tempTotolTimeRes.data) // 得到16进制字符串；
    console.log('发送指令获取测温总次数:', tempTotolTimeParse);
    let realTimes = 0;
    if (tempTotolTimeParse.length >= 4) {
      let tt = tempTotolTimeParse.substring(0, 4); //得到中间值
      // 大小端转化
      tt = (tt.slice(-2) + tt).slice(0, 4)
      realTimes = parseInt(tt, 16)
    } else {
      realTimes = 0;
    }
    console.log('总测温次数:', realTimes);
    // 4:发送指令获取测温间隔和开始测温时间
    const tempDeltaRes = await this.NFCTempWork(nfca, this.string2buffer('40b10020000b00'));
    const tempDeltaParse = this.ab2hex(tempDeltaRes.data) // 得到16进制字符串；
    console.log('测温间隔和开始测温时间:', tempDeltaParse);
    const start = parseInt(tempDeltaParse.substring(0, 8), 16); // 时间戳
    const delta = parseInt(tempDeltaParse.substring(tempDeltaParse.length - 8, tempDeltaParse.length).substring(0, 4), 16); // 间隔
    console.log('测温时间:', start, '测温间隔delta:', delta)

    // 5:发送指令获取温度超限次数;

    const exceedRes = await this.NFCTempWork(nfca, this.string2buffer('40c6c094000000'));
    const constexceedParse = this.ab2hex(exceedRes.data) // 得到16进制字符串；
    console.log('温度超限次数:', constexceedParse);

    // 6:获取最大和最小值 

    const maxAndMinRes = await this.NFCTempWork(nfca, this.string2buffer('40b1b180000400'));
    const constmaxAndMinResParse = this.ab2hex(maxAndMinRes.data) // 得到16进制字符串；
    console.log('获取最大和最小值 :', constmaxAndMinResParse);
    let maxTm = this.getTp(constmaxAndMinResParse.substring(0, 4))
    let minTm = this.getTp(constmaxAndMinResParse.substring(4, 8))
    console.log('最大温度:', maxTm, "最小温度:", minTm)

    // 7:发送指令 检查测温状态
    const temStatusRes = await this.NFCTempWork(nfca, this.string2buffer('40cf0100000000'));
    const statusParse = this.ab2hex(temStatusRes.data) // 得到16进制字符串；
    console.log('检查测温状态 :', statusParse);

    if (statusParse.substring(4, 5) == '0') {
      // 重新发送新的指令获取实际测温次数
      return
    } else {
      const realTimeRes = await this.NFCTempWork(nfca, this.string2buffer('40b1b188000000')); // 获取实际的测温次数
      const statusParse = this.ab2hex(realTimeRes.data) // 得到16进制字符串；
      console.log('实际测温次数的16进制字符串:',statusParse)
      // 交换大小端；
      let times = (statusParse.slice(-2) + statusParse).slice(0, 4)
      let timesDec = parseInt(times, 16);

      timesDec += 1; // 测量次数；
      console.log('获取实际测量次数； :', timesDec);

      let dataSize = timesDec * 4;
      if (dataSize > allDataSize) { // 如果超过maxsize 数据异常。

      }
      debugger

    }
  },
  getTempDetailA() {
    const totalSize = 0;
    // x 高位 y 地位 ,n 读取大小,count 次数,p 余数    
    let x = 0x10,
      y = 0x00,
      n = 0xf8,
      count = 1,
      p = 0;
    p = totalSize % 252;
    count = totalSize / 252;
    if (p != 0) {
      count = count + 1;
    }
    let statusCode = BT_OPERATION_FAILED;
    let dataCount = 0;
    let intValue = 0;
    let result, cmdStr, xyStr, nStr, tempStr;
    let fValue = 0;


    for (let i = 0; i < count; i++) {
      if (i == 0) {
        y = 0x00;
      } else if (i == 1) {
        y = y + 0xfc;
      } else {
        x = x + 0x01;
        y = y - 0x04;
      }
      if (p != 0 && i == count - 1) {
        n = p - count * 4;
      }
      if (i == 76) {
        n = 44;
      }

      // xyStr = [NSString stringWithFormat: @ "%@%@", [CommonUtils getHexByDecimal: x digit: 2],
      //   [CommonUtils getHexByDecimal: y digit: 2]
      // ];
      // nStr = [CommonUtils getHexByDecimal: n digit: 2];
      // cmdStr = [NSString stringWithFormat: GET_TAG_CMD(GET_DETAIL, cmdType), xyStr, nStr];
      // result = [tagObj sendAPDU: cmdStr code: & statusCode withHead: YES];
      // if (statusCode != BT_SUCCESS) {
      //   [self showMsgOnSession: _session message: [NSString stringWithFormat: @ "command:%@ send failed,code:%ld", cmdStr, statusCode] noCallback: NO];
      //   return NO;
      // }
      // if ([result isEqualToString: FM_DETAIL_END]) {
      //   break;
      // }
      if (result.length % 4 != 0) {
        return NO;
      }
      dataCount = result.length / 8;
      // TempDetail * item;
      for (let j = 0; j < dataCount; j++) {
        // item = [
        //   [TempDetail alloc] init
        // ];
        // tempStr = [result substringWithRange: NSMakeRange(2 * j * 4, 4)];
        // item.tempID = [NSString stringWithFormat: @ "%d", j + 1];
        // item.hexTemp = tempStr;
        // fValue = [self getTemperatureFromHex: tempStr];
        // tempStr = [NSString stringWithFormat: @ "%.2f", fValue];
        // item.decimalTemp = tempStr;
        // intValue = msg.startTime + j * msg.intervalSeconds;
        // item.opTime = [CommonUtils timestampSwitchTime: intValue andFormatter: @ "YYYY-MM-dd HH:mm:ss"];
        // [msg.temperaturesArray addObject: item];
      }
    }

  }




})